const app = getApp()
Component({
  properties: {
    index: {
      type: Number,
      value: 0
    }
  },
  data: {
    selected: 0,
    safeArea: '',
    navList: [{
      pagePath: "/pages/index/index",
      iconPath: "",
      selectedIconPath: "",
      text: "排好的"
    }, {
      pagePath: "/pages/tpl/tpl",
      iconPath: "",
      selectedIconPath: "",
      text: "模板"
    }, {
      pagePath: "/pages/photo/index",
      iconPath: "",
      selectedIconPath: "",
      text: "图库"
    }],
    bannerList: ["../../images/banner1.jpg", "../../images/banner2.jpg"],
    opt: {
      tabWidthList: [],
      tabHeight: 0,
      height: 0,
      width: 0,
      currentIndex: 0,
      animating: false,
      nextIndex: 0,
      distance: 0,
      avgSpeed: 0,
      curDisX: 0
    },
    inited: false
  },
  lifetimes: {
    attached() {
    },
    ready: function () {
    },
    detached: function () {
      // 在组件实例被从页面节点树移除时执行
    },
  },
  pageLifetimes: {
    show() {
      if (!this.data.inited) {
        const rect = wx.getMenuButtonBoundingClientRect()
        this.setData({
          safeArea: `padding-top:${rect.bottom}px`
        })
        this.init()
        this.setData({
          inited: true
        })
      }
    }
  },
  methods: {
    init() {
      const query = wx.createSelectorQuery().in(this)
      query.select('#navCanvas')
        .fields({ node: true, size: true })
        .exec(async (res) => {
          if (res[0]) {
            const canvas = res[0].node
            const ctx = canvas.getContext('2d')
            this.canvas = canvas
            this.ctx = ctx
            this.calcTabs()
          }
        })
    },
    // nav点击事件
    navTap(e) {
      const { index } = e.currentTarget.dataset
      // 切换页面
      const url = this.data.navList[index].pagePath
      wx.switchTab({
        url,
        fail: console.error
      })
    },
    // 切换tab页
    switchTab(index) {
      this.setData({
        selected: index
      })
      const opt = this.data.opt
      if (index !== opt.currentIndex && opt.tabWidthList && opt.tabWidthList.length) {
        if (!opt.animating || index !== opt.nextIndex) {
          opt.animating = true
          opt.distance = opt.tabWidthList[index] - opt.tabWidthList[opt.currentIndex]
          opt.avgSpeed = this.calcAVGSpeed(opt.distance)
          opt.curDisX = 0
          opt.nextIndex = index
          this.setData({
            opt: opt
          })
        }
      }
    },
    // 计算均速速
    calcAVGSpeed(distance) {
      const speed = (4 * 0.85 * distance + 10 * (1 - 0.85) * distance) / (10 * 4 * 20);
      return Math.max(Math.abs(speed), 2.5) * Math.sign(speed)
    },
    // 计算tabs导航
    calcTabs() {
      const offsetArr = []
      let offset = 0
      const query = wx.createSelectorQuery().in(this)
      query.selectAll(".nav-item").boundingClientRect((res) => {
        for (const item of res) {
          offsetArr.push(offset)
          offset += item.width
        }
        offsetArr[0] = -20
        offsetArr.push(offset)
        offsetArr[offsetArr.length - 1] = offsetArr[offsetArr.length - 1] + 20
        const opt = this.data.opt
        opt.tabWidthList = offsetArr
        opt.tabHeight = res[0].height
        opt.height = res[0].height + 20
        opt.width = wx.getWindowInfo().windowWidth
        this.setData({
          opt: opt
        })
        this.initCanvas(opt.width, opt.height)
        this.draw(0)
        this.switchTab(this.data.index)
      }).exec()
    },
    // 初始化canvas
    initCanvas(width, height) {
      const pixelRatio = wx.getWindowInfo().pixelRatio;
      const canvas = this.canvas
      canvas.width = width * pixelRatio
      canvas.height = height * pixelRatio
      this.ctx.fillStyle = "#ccbd9d"
      this.ctx.scale(pixelRatio, pixelRatio)
    },
    // 创建图案
    createPattern() {
      const width = 140,
        height = 63,
        scale = 1,
        canvas = wx.createCanvas();
      const ctx = canvas.getContext('2d')
      canvas.width = width
      canvas.height = height
      canvas.style.width = width / scale + 'px'
      canvas.style.height = height / scale + 'px'
      ctx.scale(scale, scale)
      ctx.lineWidth = 0.4
      for (var g = 3, h = 0.8, j = 1; 30 > j; j++) {
        //设置或返回用于笔触的颜色、渐变或模式
        ctx.strokeStyle = "RGBA(204, 189, 157, " + h + ")";
        //开始一条路径
        ctx.beginPath();
        //把路径移动到画布中的指定点，不创建线条
        ctx.moveTo(0, j * g);
        //添加一个新点，然后在画布中创建从该点到最后指定点的线条
        ctx.lineTo(b, j * g);
        //绘制已定义的路径
        ctx.stroke();
        //创建从当前点回到起始点的路径
        ctx.closePath();
        10 < j && (h -= 0.1);
      }
      const pattern = this.canvas.getContext("2d").createPattern(canvas, "repeat-x");
      this.setData({
        ['opt.pattern']: pattern
      })
      canvas = null
    },
    draw(speed) {
      const _this = this
      this._drawHightlight(speed);
      const timer = this.canvas.requestAnimationFrame(function () {
        _this.draw((speed + 0.005) % 1.6);
      });
      this.setData({
        ['opt.timer']: timer
      })
    },
    _drawHightlight(speed) {
      const opt = this.data.opt
      const ctx = this.ctx,
        d = 0.3;
      ctx.clearRect(0, 0, 2 * opt.width, 2 * opt.height);
      ctx.shadowColor = "rgba(0, 193, 220, 1)";
      ctx.shadowBlur = 5;
      ctx.strokeStyle = "#004CB3";
      ctx.lineWidth = 0.8;
      ctx.fillStyle = "none";
      this._draw(ctx, false);
      //这里绘制了外围边框线条
      const line = ctx.createLinearGradient(0, 0, opt.width, opt.height),
        f = speed - d;
      line.addColorStop(Math.min(1, Math.max(0, 0 + f)), "rgba(0,0,0,0)");
      line.addColorStop(Math.min(1, Math.max(0, 0 + f + 0.1)), "#8ED6FF");
      line.addColorStop(Math.min(1, 0 + f + d), "#8ED6FF");
      line.addColorStop(Math.min(1, 0 + f + d + 0.1), "rgba(0,0,0,0)");
      line.addColorStop(1, "rgba(0,0,0,0)");
      ctx.lineWidth = 1.5;
      ctx.strokeStyle = line;
      // ctx.fillStyle = opt.pattern;
      this._draw(ctx, true);
    },
    _draw(ctx, flag) {
      const opt = this.data.opt;
      let navIndex = opt.currentIndex,
        tableHeight = opt.tabHeight,
        f = 0,
        g = 40,
        i = 20,
        j = 0.5,
        k = 2.5,
        l = 0;
      if (
        (ctx.beginPath(),
          ctx.moveTo(-50, opt.height + 10),
          ctx.lineTo(-50, tableHeight + j),
          opt.animating)
      ) {
        const m = this.getCurSpeed(opt.curDisX, opt.distance);
        l = Math.min(Math.abs(opt.distance), Math.abs(opt.curDisX + m)) * Math.sign(m);
      }
      if (
        (ctx.lineTo(
          f + opt.tabWidthList[navIndex] + l - g / 2,
          tableHeight + j
        ),
          this._drawCurve(
            f + opt.tabWidthList[navIndex] + l - g / 2,
            tableHeight + j,
            f + opt.tabWidthList[navIndex] + l + g / 2,
            k + j,
            ctx,
            i
          ),
          opt.animating)
      ) {
        var o =
          opt.tabWidthList[opt.nextIndex + 1] -
          opt.tabWidthList[opt.nextIndex];
        ctx.lineTo(
          f + opt.tabWidthList[navIndex] + o + l - g / 2,
          k + j
        ),
          this._drawCurve(
            f + opt.tabWidthList[navIndex] + o + l - g / 2,
            k + j,
            f + opt.tabWidthList[navIndex] + o + l + g / 2,
            tableHeight + j,
            ctx,
            i
          );
      } else {
        //lineTO添加一个新点 宽度长度
        ctx.lineTo(
          f + opt.tabWidthList[navIndex + 1] + l - g / 2,
          k + j
        );
        this._drawCurve(
          f + opt.tabWidthList[navIndex + 1] + l - g / 2,
          k + j,
          f + opt.tabWidthList[navIndex + 1] + l + g / 2,
          tableHeight + j,
          ctx,
          i
        );
      }
      ctx.lineTo(opt.width + 10, tableHeight + j);
      ctx.lineTo(opt.width + 10, opt.height + 10);
      ctx.closePath();
      ctx.stroke();
      flag && ctx.fill();
      if (opt.animating && flag) {
        this.setData({
          ['opt.curDisX']: l
        })
        if (Math.abs(l) >= Math.abs(opt.distance)) {
          this.setData({
            ['opt.animating']: false,
            ['opt.currentIndex']: opt.nextIndex
          })
        }
      }
    },
    getCurSpeed(a, b) {
      const opt = this.data.opt
      var speed = Math.abs(a) > Math.abs(0.85 * b) ? 4 * opt.avgSpeed : 10 * opt.avgSpeed;
      return speed;
    },
    _drawCurve(x, y, x1, y1, ctx, f) {
      ctx.bezierCurveTo(x + f, y, x1 - f, y1, x1, y1);
    },
  }
})